package cn.changein.framework.service.setting.client.impl;

import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.changein.framework.base.auth.context.LoginContextHolder;
import cn.changein.framework.base.pojo.page.PageFactory;
import cn.changein.framework.base.pojo.page.PageInfo;
import cn.changein.framework.constant.AuditConstants;
import cn.changein.framework.kernel.model.response.ResponseData;
import cn.changein.framework.model.setting.client.entity.Client;
import cn.changein.framework.model.setting.client.mapper.ClientMapper;
import cn.changein.framework.model.setting.client.model.params.ClientParam;
import cn.changein.framework.model.setting.client.model.result.ClientResult;
import cn.changein.framework.model.setting.client.model.result.ImportClientResult;
import cn.changein.framework.model.setting.contactType.entity.ContactType;
import cn.changein.framework.model.setting.contactType.mapper.ContactTypeMapper;
import cn.changein.framework.service.setting.client.ClientService;
import cn.changein.framework.util.ExcelUtil;
import cn.changein.framework.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.*;

/**
 * <p>
 * 客户 服务实现类
 * </p>
 *

 * @Date 2020-11-02
 * @Copyright: companyName
 * @Version 1.0
 * @Since JDK1.8
 */
@Service
public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> implements ClientService {


    private static final Integer DELETE_FLAG = 0;

    @Autowired(required = false)
    private ClientMapper clientMapper;

    @Autowired(required = false)
    private ContactTypeMapper contactTypeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData add(ClientParam param) {
        if (StringUtils.isEmpty(param.getClientCode()) || StringUtils.isEmpty(param.getClientName())) {
            return ResponseData.error("添加的客户代码以及客户名称不能为空");
        }
        // 校验客户代码是否重复
        Integer clientCode = this.baseMapper.countByClientCode(param.getClientCode(), param.getId(), DELETE_FLAG);
        if (clientCode != null && clientCode > 0) {
            return ResponseData.error(param.getClientCode() + "已存在");
        }
        if (StringUtils.isNotEmpty(param.getOuterCode())) {
            // 校验外部编码是否重复
            Integer outerCode = this.baseMapper.countByOuterCode(param.getOuterCode(), param.getId(), DELETE_FLAG);
            if (outerCode != null && outerCode > 0) {
                return ResponseData.error(param.getOuterCode() + "已存在");
            }
        }
        Client entity = getEntity(param);
        this.save(entity);
        return ResponseData.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData update(ClientParam param) {
        if (param.getId() == null) {
            return ResponseData.error("修改异常");
        }
        if (StringUtils.isEmpty(param.getClientCode()) || StringUtils.isEmpty(param.getClientName())) {
            return ResponseData.error("修改的客户代码以及客户名称不能为空");
        }
        // 根据客户ID以及客户代码查询
        QueryWrapper<Client> wrapper = new QueryWrapper<>();
        wrapper.eq("id", param.getId());
        wrapper.eq("client_code", param.getClientCode());
        Client client = this.baseMapper.selectOne(wrapper);
        if (client == null) {
            return ResponseData.error("客户代码无法修改");
        }
        if (StringUtils.isNotEmpty(param.getOuterCode())) {
            // 校验外部编码是否重复
            Integer outerCode = this.baseMapper.countByOuterCode(param.getOuterCode(), param.getId(), DELETE_FLAG);
            if (outerCode != null && outerCode > 0) {
                return ResponseData.error(param.getOuterCode() + "已存在");
            }
        }
        Client oldEntity = getOldEntity(param);
        Client newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
        return ResponseData.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData delete(ClientParam param) {
        Long id = param.getId();
        if (id == null) {
            return ResponseData.error("删除异常");
        }
        Client client = getById(id);
        String clientName = client.getClientName();
        // 校验删除的客户是否未审核
        if (client.getAudit().equals(AuditConstants.AUDIT)) {
            return ResponseData.error(clientName + "已审核");
        }
        removeById(id);
        return ResponseData.success();
    }

    @Override
    public ClientResult findBySpec(ClientParam param) {
        return this.baseMapper.findBySpec(param);
    }

    @Override
    public List<ClientResult> findListBySpec(ClientParam param) {
        return this.baseMapper.customList(param);
    }

    @Override
    public PageInfo findPageBySpec(ClientParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return PageFactory.createPageInfo(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData updateState(ClientParam clientParam) {
        String ids = clientParam.getIds();
        if (StringUtils.isNotEmpty(ids)) {
            String[] idArr = ids.split(",");
            for (String id : idArr) {
                Client client = this.getById(Long.parseLong(id));
                Integer state = client.getState();
                client.setState(state == 0 ? 1 : 0);
                this.baseMapper.updateById(client);
            }
        } else {
            ResponseData.error("未查到相关数据");
        }
        return ResponseData.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData updateAudit(ClientParam clientParam) {
        String ids = clientParam.getIds();
        if (StringUtils.isNotEmpty(ids)) {
            Integer audit = clientParam.getAudit();
            String[] idArr = ids.split(",");
            List<Client> batchList = new ArrayList<>();
            // 审核
            if (Objects.equals(AuditConstants.AUDIT, audit)) {
                for (String id : idArr) {
                    Client client = this.getById(Long.parseLong(id));
                    client.setAudit(audit);
                    client.setAuditTime(new Date());
                    client.setAuditor(LoginContextHolder.getContext().getUserId());
                    batchList.add(client);
                }

                // 反审核
            } else {
                for (String id : idArr) {
                    Client client = this.getById(Long.parseLong(id));
                    client.setAudit(audit);
                    client.setAuditTime(null);
                    client.setAuditor(null);
                    batchList.add(client);
                }
            }
            this.updateBatchById(batchList);
        } else {
            ResponseData.error("未查到相关数据");
        }
        return ResponseData.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData deleteList(ClientParam clientParam) {
        if (StringUtils.isEmpty(clientParam.getIds())) {
            return ResponseData.error("请选择至少一条数据");
        }
        List<Long> batchIdList = new ArrayList<>();
        StringBuilder resultMsg = new StringBuilder();
        String[] clientIds = clientParam.getIds().split(",");
        for (String clientId : clientIds) {
            Client client = getById(clientId);
            Long id = client.getId();
            String clientName = client.getClientName();
            // 校验删除的客户是否未审核
            if (client.getAudit().equals(AuditConstants.AUDIT)) {
                resultMsg.append(clientName).append("已审核，");
                continue;
            }
            batchIdList.add(id);
        }
        if (batchIdList.size() > 0) {
            removeByIds(batchIdList);
        }
        if (resultMsg.length() == 0) {
            return ResponseData.success();
        }
        return ResponseData.error(resultMsg.toString().substring(0, resultMsg.length() - 1));
    }

    @Override
    public void exportBusinessUnit(ClientParam clientParam, HttpServletResponse response) {
        // 验证用户是否勾选了数据导出
        List<ClientResult> clientResultList;
        if (org.springframework.util.StringUtils.isEmpty(clientParam.getIds())) {
            clientResultList = this.baseMapper.customList(clientParam);
        } else {
            String[] clientIds = clientParam.getIds().split(",");
            clientResultList = this.baseMapper.listClientIds(clientIds, DELETE_FLAG);
        }
        if (clientResultList != null || clientResultList.size() > 0) {
            for (ClientResult clientResult : clientResultList) {
                clientResult.setStatus(("0".equals(clientResult.getState() + "") ? "否" : "是"));
                clientResult.setExportAudit(("0".equals(clientResult.getAudit() + "") ? "未审核" : "已审核"));
            }
        }
        try {
            ExcelUtil.exportExcel(clientResultList, null, "客户列表", ClientResult.class, "客户列表", response);
        } catch (Exception e) {
            log.error("客户Excel导出异常！", e);
        }
    }

    /**
     * 导入excel
     *

     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData importExcel(MultipartFile file) {
        StringBuffer globalMsg = new StringBuffer();
        try {
            ExcelImportResult<ImportClientResult> importExcelVerify = ExcelUtil.importExcelVerify(file, 0, 1, ImportClientResult.class);
            //错误数据
            List<ImportClientResult> failList = importExcelVerify.getFailList();

            //正确数据
            List<ImportClientResult> clientResultlList = importExcelVerify.getList();

            List<Client> clientList = new ArrayList<>();

            if (failList != null && failList.size() > 0) {
                for (ImportClientResult result : failList) {
                    int rowNum = result.getRowNum() + 1;
                    String errorMsg = result.getErrorMsg();
                    globalMsg.append("<br/>第" + rowNum + "行: " + errorMsg + "。");
                }
            }

            List<String> contactTypeNameToAddList = new ArrayList<>();
            if (clientResultlList != null && clientResultlList.size() > 0) {
                //处理正确数据
                List<String> clientCodeList = this.clientMapper.getCodeList();
                List<String> clientOuterCodeList = this.clientMapper.getOuterCodeList();
                List<String> contactTypeNameList = contactTypeMapper.getNameList();

                for (ImportClientResult clientResult : clientResultlList) {
                    String rowMsg = "<br/>第" + clientResult.getRowNum() + "行";
                    StringBuffer msg = new StringBuffer();
                    String outerCode = clientResult.getOuterCode();
                    String code = clientResult.getClientCode();
                    String contactTypeName = clientResult.getContactType();

                    //判断编码是否存在
                    if (clientCodeList.contains(code)) {
                        msg.append("[编码]已经存在，");
                    } else {
                        clientCodeList.add(code);
                    }
                    //判断外部编码是否存在
                    if (clientOuterCodeList.contains(outerCode)) {
                        msg.append("[外部编码]已经存在，");
                    } else {
                        clientOuterCodeList.add(outerCode);
                    }
                    //判断单位类型是否存在
                    if (!(contactTypeNameList.contains(contactTypeName) || contactTypeNameToAddList.contains(contactTypeName))) {
                        contactTypeNameToAddList.add(contactTypeName);
                    }
                    if (msg.length() == 0) {
                        Client client = new Client();
                        ToolUtil.copyProperties(clientResult, client);
                        clientList.add(client);
                    } else {
                        globalMsg.append(rowMsg + msg.deleteCharAt(msg.length() - 1).toString() + "。");
                    }
                }
            }

            //如果不报错的话
            if (globalMsg.length() == 0) {
                //添加新的单位类型到数据库
                if (contactTypeNameToAddList.size() > 0) {
                    for (String name : contactTypeNameToAddList) {
                        ContactType contactType = new ContactType();
                        contactType.setName(name);
                        contactTypeMapper.insert(contactType);
                    }
                }
                List<ContactType> contactTypeList = contactTypeMapper.selectList(new QueryWrapper<>());
                HashMap<String, Long> contactTypeMap = new HashMap<>();
                if (contactTypeList != null && contactTypeList.size() > 0) {
                    for (ContactType contactType : contactTypeList) {
                        String name = contactType.getName();
                        Long id = contactType.getId();
                        contactTypeMap.put(name, id);
                    }
                }
                //根据contactTypeName设置对应的contactTypeId
                if (clientList.size() > 0) {
                    for (Client client : clientList) {
                        String contactTypeName = client.getContactType();
                        if (contactTypeName != null) {
                            Long contactTypeId = contactTypeMap.get(contactTypeName);
                            client.setContactTypeId(contactTypeId);
                        }
                    }
                    //保存
                    saveBatch(clientList);
                } else {
                    return ResponseData.error("请在文件中添加数据！");
                }
            } else {
                return ResponseData.error("导入错误！ " + globalMsg.toString());
            }
        } catch (Exception e) {
            log.error("导入异常！", e);
            return ResponseData.error("导入失败");
        }
        return ResponseData.success("导入成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateQuotedCount(Long id, Integer quotedCount) {
        baseMapper.updateQuotedCount(id, quotedCount);
    }

    private Serializable getKey(ClientParam param) {
        return param.getId();
    }

    private Page getPageContext() {
        return PageFactory.defaultPage();
    }

    private Client getOldEntity(ClientParam param) {
        return this.getById(getKey(param));
    }

    private Client getEntity(ClientParam param) {
        Client entity = new Client();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

}
